<?php

namespace app\admin\model\supplier;

use think\facade\Db;
use app\common\model\Export;

class Mobile
{
    private $table = 'mobile_supplier';

    /**
     * 列表.
     */
    public function getList($params)
    {
        $where = [];
        $where[] = ['is_deleted', '=', 0];
        $name = trim($params['name'] ?? '');
        if ($name) {
            $where[] = ['name', 'like', '%' . $name . '%'];
        }
        $paginate = [
            'page' => $params['page'] ?? 1,
            'list_rows' => $params['list_rows'] ?? 10,
        ];
        $list = Db::name($this->table)
            ->where($where)
            ->order('sort desc, id desc')
            ->paginate($paginate)
            ->toArray();
        $supplierIds = array_column($list['data'], 'id');
        $stat = Db::name('mobile_supplier_stat')
            ->whereIn('mobile_supplier_id', $supplierIds)
            ->column('*', 'mobile_supplier_id');
        $fields = [
            'yidong_fast', 'yidong_slow', 'liantong_fast',
            'liantong_slow', 'dianxin_fast', 'dianxin_slow',
        ];
        foreach ($list['data'] as $k => $v) {
            foreach ($fields as $field) {
                $list['data'][$k][$field] = json_decode($v[$field], true);
            }
            $list['data'][$k]['stat'] = $stat[$v['id']] ?? '';
            $list['data'][$k]['discount_slow_all'] = json_decode($v['discount_slow_all']) ?? [];
            $list['data'][$k]['discount_fast_all'] = json_decode($v['discount_fast_all']) ?? [];
        }

        return success('操作成功', $list);
    }

    /**
     * 代理商关联表.
     */
    public function getAgentList($params)
    {
        $where = [];
        $where[] = ['agent.is_deleted', '=', 0];
        $username = trim($params['username'] ?? '');
        if ($username) {
            $where[] = ['agent.username|agent.mobile|agent.company_name', 'like', $username . '%'];
        }
        if (!empty($params['mobile_discount_fast'])) {
            $where[] = ['c.discount_fast_all', 'like', '%' . number_format($params['mobile_discount_fast'], 2) . '%'];
        }
        if (!empty($params['mobile_discount_slow'])) {
            $where[] = ['c.discount_slow_all', 'like', '%' . number_format($params['mobile_discount_slow'], 2) . '%'];
        }
        if (!empty($params['settle_type'])) {
            $where[] = ['agent.settle_type', '=', $params['settle_type']];
        }
        $agentIds = Db::name('agent_mobile_supplier')
            ->where('mobile_supplier_id', $params['mobile_supplier_id'])
            ->column('agent_id');
        if (!empty($params['checked'])) {
            if (1 == $params['checked']) {
                $where[] = ['agent.id', 'in', $agentIds];
            } else {
                $where[] = ['agent.id', 'not in', $agentIds];
            }
        }
        $paginate = [
            'page' => $params['page'] ?? 1,
            'list_rows' => $params['list_rows'] ?? 10,
        ];
        $where[] = ['c.serv_type', '=', PRODUCT_MOBILE_SERV];
        $list = Db::name('agent')
            ->field('agent.id, username, mobile, mobile_discount_fast, mobile_discount_slow,
            settle_type, company_name, c.discount_fast_all, c.discount_slow_all')
            ->join('agent_service_config c', 'agent.id=c.agent_id', 'left')
            ->where($where)
            ->order('id desc')
            ->paginate($paginate)
            ->toArray();
        foreach ($list['data'] as $k => $v) {
            $list['data'][$k]['checked'] = in_array($v['id'], $agentIds) ? 1 : 2;
            $list['data'][$k]['discount_fast_all'] = json_decode($v['discount_fast_all'], true);
            $list['data'][$k]['discount_slow_all'] = json_decode($v['discount_slow_all'], true);
        }

        return success('操作成功', $list);
    }

    /**
     * 关联代理商.
     */
    public function associationAgent($params)
    {
        if (empty($params['mobile_supplier_id'])) {
            return fail('话费供应商 id 不能为空');
        }
        if (empty($params['agent_ids'])) {
            return fail('请选择代理商');
        }
        if (!isset($params['checked'])) {
            return fail('关联状态有误');
        }

        $insert = [];
        $delete = [];
        if (1 == $params['checked']) {
            // 关联
            $old = Db::name('agent_mobile_supplier')
                ->where('mobile_supplier_id', $params['mobile_supplier_id'])
                ->column('agent_id');
            $insertIds = array_diff($params['agent_ids'], $old);
            foreach ($insertIds as $agentId) {
                $insert[] = [
                    'agent_id' => $agentId,
                    'mobile_supplier_id' => $params['mobile_supplier_id'],
                ];
            }
        } else {
            // 取消关联
            $delete = $params['agent_ids'];
        }

        Db::startTrans();
        try {
            if ($insert) {
                Db::name('agent_mobile_supplier')
                    ->insertAll($insert);
            }
            if ($delete) {
                Db::name('agent_mobile_supplier')
                    ->where('mobile_supplier_id', $params['mobile_supplier_id'])
                    ->whereIn('agent_id', $delete)
                    ->delete();
            }

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            return fail('操作失败：' . $e->getMessage());
        }

        return success('操作成功');
    }

    /**
     * 添加
     */
    public function create($params)
    {
        $unique = Db::name($this->table)
            ->where('name', $params['name'])
            ->where('is_deleted', 0)
            ->value('id');
        if ($unique) {
            return fail('该名称已经被占用');
        }
        $code = Db::name($this->table)
            ->where('code', $params['code'])
            ->where('is_deleted', 0)
            ->value('code');
        if ($code) {
            return fail('该代号已经被占用');
        }

        array_walk($params['discount_fast_all'], 'my_number_format');
        array_walk($params['discount_slow_all'], 'my_number_format');

        $unique = Db::name($this->table)
            ->where('code', $params['code'])
            ->where('url', $params['url'])
            ->value('id');

        Db::startTrans();
        try {
            $id = Db::name($this->table)
                ->insertGetId([
                    'name' => $params['name'],

                    // 根据号码段，匹配不到运营商的话，使用三个运营商最高的折扣，保证不亏
                    'discount_slow' => max($params['discount_slow_all']),
                    'discount_fast' => max($params['discount_fast_all']),

                    // 折扣区分运营商
                    'discount_slow_all' => json_encode($params['discount_slow_all']),
                    'discount_fast_all' => json_encode($params['discount_fast_all']),

                    'code' => $params['code'],
                    'url' => $params['url'],
                    'app_id' => $params['app_id'],
                    'app_secret' => $params['app_secret'],
                    'priority_slow' => intval($params['priority_slow']),
                    'priority_fast' => intval($params['priority_fast']),
                    'yidong_fast' => json_encode($params['yidong_fast'] ?? []),
                    'yidong_slow' => json_encode($params['yidong_slow'] ?? []),
                    'liantong_fast' => json_encode($params['liantong_fast'] ?? []),
                    'liantong_slow' => json_encode($params['liantong_slow'] ?? []),
                    'dianxin_fast' => json_encode($params['dianxin_fast'] ?? []),
                    'dianxin_slow' => json_encode($params['dianxin_slow'] ?? []),
                    'balance' => 0,
                    'is_main' => empty($unique) ? 1 : 0,
                ]);
            Db::name('mobile_supplier_stat')
                ->insert([
                    'mobile_supplier_id' => $id,
                ]);
            Db::name($this->table)
                ->where('id', $id)
                ->update([
                    'sort' => $id,
                ]);

            $this->dealSupplierPriority();

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            return fail('添加失败：' . $e->getMessage());
        }

        return success('添加成功', [
            'id' => intval($id),
        ]);
    }

    /**
     * 编辑.
     */
    public function edit($params)
    {
        $info = Db::name($this->table)
            ->field('name, code')
            ->where('id', $params['id'])
            ->where('is_deleted', 0)
            ->find();
        if (empty($info)) {
            return fail('供应商不存在');
        }
        if ($info['name'] != $params['name']) {
            $name = Db::name($this->table)
                ->where('name', $params['name'])
                ->where('is_deleted', 0)
                ->value('name');
            if ($name) {
                return fail('该名称已经被占用');
            }
        }
        if ($info['code'] != $params['code']) {
            $code = Db::name($this->table)
                ->where('code', $params['code'])
                ->where('is_deleted', 0)
                ->value('code');
            if ($code) {
                return fail('该代号已经被占用');
            }
        }

        array_walk($params['discount_fast_all'], 'my_number_format');
        array_walk($params['discount_slow_all'], 'my_number_format');

        $update = [
            'name' => $params['name'],

            // 根据号码段，匹配不到运营商的话，使用三个运营商最高的折扣，保证不亏
            'discount_slow' => max($params['discount_slow_all']),
            'discount_fast' => max($params['discount_fast_all']),

            // 折扣区分运营商
            'discount_slow_all' => json_encode($params['discount_slow_all']),
            'discount_fast_all' => json_encode($params['discount_fast_all']),

            'code' => $params['code'],
            'url' => $params['url'],
            'app_id' => $params['app_id'],
            'app_secret' => $params['app_secret'],
            'priority_slow' => intval($params['priority_slow']),
            'priority_fast' => intval($params['priority_fast']),
            'yidong_fast' => json_encode($params['yidong_fast'] ?? []),
            'yidong_slow' => json_encode($params['yidong_slow'] ?? []),
            'liantong_fast' => json_encode($params['liantong_fast'] ?? []),
            'liantong_slow' => json_encode($params['liantong_slow'] ?? []),
            'dianxin_fast' => json_encode($params['dianxin_fast'] ?? []),
            'dianxin_slow' => json_encode($params['dianxin_slow'] ?? []),
        ];

        Db::startTrans();
        try {
            Db::name($this->table)
                ->where('id', $params['id'])
                ->update($update);

            $this->dealSupplierPriority();

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            return fail('更新失败：' . $e->getMessage());
        }

        return success('更新成功', [
            'id' => intval($params['id']),
        ]);
    }

    /**
     * 删除.
     */
    public function delete($params)
    {
        if (empty($params['id'])) {
            return fail('参数有误');
        }
        $info = Db::name($this->table)
            ->where('id', $params['id'])
            ->where('is_deleted', 0)
            ->find();
        if (empty($info)) {
            return success('删除成功');
        }

        Db::startTrans();
        try {
            Db::name($this->table)
                ->where('id', $info['id'])
                ->update([
                    'is_deleted' => 1,
                    'deleted_at' => date('Y-m-d H:i:s'),
                ]);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            return fail('删除失败: ' . $e->getMessage());
        }

        return success('删除成功');
    }

    /**
     * 获取供应商账户余额.
     */
    public function getBalance($id)
    {
        $info = Db::name($this->table)
            ->where('id', $id)
            ->where('is_deleted', 0)
            ->find();
        if (empty($info)) {
            return fail('供应商不存在');
        }

        try {
            if (false === strpos($info['code'], '\\')) {
                $code = explode('-', $info['code'])[0]; // lechong，lechong-1024 都调用 \api\mobile\Lechong 这个类
                $class = '\\api\\mobile\\' . ucfirst($code);
            } else {
                $class = $info['code'];
            }
            if (!class_exists($class)) {
                return fail('该供应商不支持余额查询');
            }
            $model = new $class($info);
            $balance = $model->queryAmount();
            if (false === $balance) {
                return fail($model->getError());
            }
            Db::name($this->table)
                ->where('id', $id)
                ->update([
                    'balance' => $balance,
                ]);
        } catch (\Exception $e) {
            return fail('供应商代号有误：' . $e->getMessage());
        }

        return success('操作成功', [
            'balance' => $balance,
        ]);
    }

    /**
     * 处理话费供应商优先级
     * 用于下单的时候，判断选择哪个话费供应商.
     */
    private function dealSupplierPriority()
    {
        $list = Db::name('mobile_supplier')
            ->field('id, priority_slow, priority_fast, yidong_slow, yidong_fast,
            liantong_slow, liantong_fast, dianxin_fast, dianxin_slow')
            ->where('is_deleted', 0)
            ->select()
            ->toArray();

        $fields = [
            'yidong_slow', 'yidong_fast',
            'liantong_slow', 'liantong_fast',
            'dianxin_slow', 'dianxin_fast',
        ];
        $result = [];
        foreach ($list as $k => $v) {
            foreach ($fields as $field) {
                $amount = json_decode($v[$field], true);
                if (strpos($field, '_fast')) {
                    $other = 'other_fast';
                    $priority = 'priority_fast';
                } else {
                    $other = 'other_slow';
                    $priority = 'priority_slow';
                }
                if (empty($amount) || empty($v[$priority])) {
                    continue;
                }
                //运营商快慢充+金额+供应商 =
                foreach ($amount as $v3) {
                    $result[$field][$v3][$v['id']] = $v[$priority];
                    $result[$other][$v3][$v['id']] = $v[$priority];
                }
            }
        }
        $filename = root_path() . '/data/mobileSupplierPriority.json';
        file_put_contents($filename, json_encode($result));
    }

    /**
     * 每日资金明细
     */
    public function getDailyBalanceList($params)
    {
        $where = [];
        $where[] = ['is_deleted', '=', 0];
        $where[] = ['is_main', '=', 1];
        $name = trim($params['name'] ?? '');
        if ($name) {
            $where[] = ['name', 'like', '%' . $name . '%'];
        }
        if (empty($params['dateymd'])) {
            $params['dateymd'] = [
                date('Y-m-d', strtotime('-7 days')),
                date('Y-m-d', strtotime('-1 days')),
            ];
        }
        $days = ceil((strtotime($params['dateymd'][1]) - strtotime($params['dateymd'][0])) / 86400);
        if ($days > 31) {
            return fail('时间跨度不能超过 31 天');
        }

        $paginate = [
            'page' => $params['page'] ?? 1,
            'list_rows' => $params['list_rows'] ?? 10,
        ];

        if (!empty($params['is_export'])) {
            $list = Db::name('mobile_supplier')
                ->field('id, name, balance')
                ->where($where)
                ->order('id desc')
                ->select()
                ->toArray();
            if (empty($list)) {
                return fail('没有可导出的数据');
            }
            $list['data'] = $list;
        } else {
            $list = Db::name('mobile_supplier')
                ->field('id, name, balance')
                ->where($where)
                ->order('id desc')
                ->paginate($paginate)
                ->toArray();
            if (empty($list)) {
                return success('操作成功', []);
            }
        }

        $supplierIds = array_column($list['data'], 'id');
        $tmp = Db::name('mobile_supplier_daily_balance')
            ->field('supplier_id, dateymd, balance')
            ->whereIn('supplier_id', $supplierIds)
            ->whereTime('dateymd', 'between', $params['dateymd'])
            ->order('dateymd asc')
            ->select()
            ->toArray();
        $balanceList = [];
        foreach ($tmp as $v) {
            $balanceList[$v['supplier_id']][$v['dateymd']] = $v['balance'];
        }
        unset($tmp);

        $dateArr = range(strtotime($params['dateymd'][0]), strtotime($params['dateymd'][1]), 86400);
        $defaultBalance = [];
        foreach ($dateArr as $k => $v) {
            $date = date('Y-m-d', $v);
            $dateArr[$k] = $date;
            $defaultBalance[$date] = 0;
        }

        if (!empty($params['is_export'])) {
            $res = [];
            $title = array_merge(['供应商名称', '当前账户余额'], $dateArr);
            foreach ($list['data'] as $v) {
                $tmp = [
                    $v['name'] . "\t",
                    fen2yuan($v['balance']),
                ];
                foreach ($dateArr as $date) {
                    $tmp[] = fen2yuan($balanceList[$v['id']][$date] ?? 0);
                }

                $res[] = $tmp;
            }
            unset($list);
            $export = new Export;
            $name = '话费供应商每日余额明细【' . $params['dateymd'][0] . '~' . $params['dateymd'][1] . '】';
            return $export->downloadExcel($title, $res, $name);
        }

        $list['dateArr'] = $dateArr;
        foreach ($list['data'] as $k => $v) {
            $list['data'][$k] = array_merge($v, $balanceList[$v['id']] ?? $defaultBalance);
        }

        return success('操作成功', $list);
    }
}
